<template>
  <el-upload
    v-loading="isUploading"
    :element-loading-text="elementLoadingText"
    ref="uploader"
    :drag="drag"
    :limit="1"
    :action="action"
    :headers="headers"
    :on-success="onUploadSuccess"
    :before-upload="beforeUpload"
    :on-error="onUploadError"
    :on-remove="onUploadRemove"
    :accept="accept"
    :on-change="onUploadChange"
    :disabled="!!fileUri"
    :on-exceed="onExceed"
    :show-file-list="false"
    :data="data"
  >

    <slot>
      <template v-if="!!fileUri">
        <i class="el-icon-files">
          <div class="el-upload__text">
            <span v-if="download">
              <el-button
                type="text"
                size="default"
                icon="el-icon-download"
                @click.stop="onDownload"
              >点击下载</el-button>
              或
            </span>
            <el-button
              @click.stop="deleteFile"
              type="text"
              size="default"
              icon="el-icon-delete"
            >删除文件</el-button>
            重新上传
          </div>
        </i>
      </template>

      <template v-else>
        <i class="el-icon-upload"></i>

        <div class="el-upload__text">
          将文件拖到此处，或
          <em>点击上传</em>
        </div>
      </template>
    </slot>
    <div
      class="el-upload__tip"
      slot="tip"
    >
      {{this.uploadTips || this.uploadTipsText}}
      <br>
      <slot name="extra"></slot>
    </div>
  </el-upload>
</template>

<script>
export default {
  props: {
    drag: {
      type: Boolean,
      default: () => true
    },
    download: {
      type: Boolean,
      default: true
    },
    filePath: {
      type: String,
      default: null
    },
    elementLoadingText: {
      type: String,
      default: '文件上传中...'
    },
    uploadTips: {
      type: String,
      default: ''
    },
    maxFileSize: {
      type: Number,
      default: 1024 * 1024 * 5
    },
    accept: {
      Type: String,
      default: '*'
    },
    headers: {
      type: Object,
      default: () => {}
    },
    action: {
      type: String,
      default: ''
    },
    fileSuffixs: {
      type: Array,
      default: () => ['*']
    },
    data: {
      type: Object
    },
    domain: {
      type: String
    },
    resKey: {
      type: String,
      default: () => 'key'
    }
  },
  data () {
    return {
      isUploading: false
    }
  },
  watch: {
    filePath: {
      handler (val) {
        this.fileUri = val
      },
      immediate: true
    }
  },
  methods: {
    beforeUpload (file) {
      this.isUploading = true
      // this.$refs.uploader.$el.children[1].style.display = this.display
      const name = file.name

      if (this.fileSuffixs.includes('*')) {
        return true
      } else {
        if (name && name.split(',').length > 0) {
          const suffix = name.split('.').pop()
          if (this.fileSuffixs.find((i) => i === suffix)) {
            if (file.size > this.maxFileSize) {
              this.$message.error(
                `文件大小不能超过${this.renderSize(this.maxFileSize)}！`
              )
              return false
            }
          } else {
            this.$message.error(`只能上传${this.fileSuffixs.join('|')}文件！`)
            return false
          }
        } else {
          this.$message.error('请上传正确的文件')
          return false
        }
      }
    },
    onUploadChange (file, fileList) {
      this.isUploading = false
    },
    onUploadSuccess (res, file) {
      this.fileUri = this.domain
        ? this.domain + res[this.resKey]
        : res[this.resKey]
      this.$emit('update:filePath', this.fileUri)
    },
    onUploadError (err, file, fileList) {
      let errMessage = '上传失败，请稍后重试'
      let error
      try {
        err && (error = JSON.parse(err.message))
        switch (err.status) {
          case 400:
            errMessage = '错误的请求'
            break
          case 401:
            this.$store.dispatch('FedLogOut')
            errMessage =
              error && error.msg
                ? error.msg
                : error.message
                  ? error.message
                  : '登录已超时，请重新登录'
            this.$router.replace({
              name: 'login',
              params: {
                lastPath: this.$router.history.current.fullPath
              }
            })
            break
          case 403:
            errMessage =
              error && error.message
                ? `你没有「${error.message}」的权限`
                : '未授权请求'
            break
          case 404:
            errMessage = '请求的资源不存在'
            break
          case 500:
            errMessage = '服务器内部错误'
            break
        }
      } catch (e) {}

      this.$message({
        message: errMessage,
        type: 'error'
      })
    },
    deleteFile () {
      this.onUploadRemove()
    },
    onUploadRemove () {
      this.fileUri = null
      this.$refs.uploader.clearFiles()
      this.$emit('update:filePath', null)
    },
    onExceed (files, fileList) {
      console.debug('onExceed')
    },
    onDownload () {
      this.$emit('download', this.fileUri)
    },
    renderSize (value) {
      if (value == null || value === '') {
        return '0 Bytes'
      }
      var unitArr = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
      var index = 0
      var srcsize = parseFloat(value)
      index = Math.floor(Math.log(srcsize) / Math.log(1024))
      var size = srcsize / Math.pow(1024, index)
      size = size.toFixed(2) // 保留的小数位数
      return size + unitArr[index]
    }
  },
  computed: {
    uploadTipsText () {
      if (this.fileSuffixs.includes('*')) {
        return `文件大小不超过${this.renderSize(this.maxFileSize)}`
      }
      return `只能上传${this.fileSuffixs.join(
        '|'
      )}文件,且文件大小不超过${this.renderSize(this.maxFileSize)}`
    }
  }
}
</script>

<style lang="scss" scoped>
.el-upload-dragger .el-icon-files {
  font-size: 67px;
  color: #c0c4cc;
  margin: 40px 0 16px;
  line-height: 50px;
}
</style>
